<?php

namespace App\Http\Controllers\Reservation;

use App\Http\Controllers\ApiController;
use App\Models\Reservation\Reservation;
use App\Project\Reserve\Pool;
use App\Models\Reservation\Pool as PoolModel;
use App\Project\Reserve\Reserve;
use App\Project\Traits\SearchAble;
use App\Transformers\Reservation\PoolListTransformer;
use App\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;

class PoolController extends ApiController
{
    use SearchAble;

    protected $searchQueryMap = [
        'name'  => ['field' => 'tn_user_base.name', 'operator' => 'like'],
        'phone' => ['field' => 'tn_user_base.phone', 'operator' => '='],
    ];

    protected $pool;

    public function __construct()
    {
        parent::__construct();

        $this->pool = new Pool();
    }

    public function index(Request $request)
    {
        if (\Auth::user()->isAn('admin')) {
            return $this->hasNoData();
        }

        $where = $this->parseSearchQueryToWhere(
            $request->only('name', 'phone')
        );

        $data = $this->pool->listing(
            $where, $request->input('times'), $request->input('is_reception')
        );

        return $this->paginate($data, new PoolListTransformer());
    }

    public function assignTo(Request $request)
    {
        $this->validate($request, [
            'ids'          => 'required|min:1|exists:st_pools,id',
            'doctor_id'    => 'required|integer',
        ]);

        $ids         = $request->request->get('ids');
        $doctor_id   = $request->request->get('doctor_id');

        $doctor = User::simpleField()->find($doctor_id);
        if (is_null($doctor)) {
            return $this->setMessage('该医生不存在。')->hasNoData();
        }

        if (($doctor->hospital_id != \Auth::user()->hospital_id) && $doctor->isA('doctor')) {
            return $this->setMessage('无法分配给该医生。')->hasNoData();
        }

        $result = $this->pool->assignTo($doctor_id, $ids);

        return $this->response($result);
    }

    public function accept(Request $request)
    {
        $ids = $request->request->get('ids');

        $result = $this->pool->accept(\Auth::user(), $ids);

        if (($result === -1) || ($result === -2)) {
            return $this->setMessage('与排班计划冲突的患者没有接受。')->setCode(40008)->hasNoData();
        }

        return $this->response($result);
    }

    public function reject(Request $request)
    {
        $ids = Arr::wrap($request->request->get('ids'));

        $result = $this->pool->reject(\Auth::user(), $ids);

        if ($result && $result->count()) {
            $success  = $result->pluck('id')->toArray();
            $rejected = array_diff($ids, $success);

            if ($rejected) {
                $this->setMessage('部分处理成功，提交的预约包含已拒绝的数据。')->setCode(40005);
            }

            $response = ['success' => $success, 'rejected' => $rejected];
        } else {
            $this->setMessage('提交的预约已全部拒绝过了，无需重复提交。')->setCode(40006);
            $response = ['success' => false, 'rejected' => $ids];
        }

        return $this->response($response);
    }

    public function doctors(Request $request)
    {
        $id = $request->query->get('id');

        $time = PoolModel::where('id', $id)->first()
                         ->reservation()->select(['time', 'am'])->withTrashed()
                         ->first();

        $reserve = new Reserve(\Auth::user());

        $visit = $reserve->visit($time->time, function ($visit) use ($time) {
            $visit->setAm($time->am);
        });

        return $this->response($visit->flatten(2));
    }
}
